
// 初始化代码编辑器
const editor = CodeMirror(document.getElementById('editor-container'), {
    lineNumbers: true,
    mode: 'javascript',
    theme: 'dracula',
    indentUnit: 4,
    value: 'kongzhitai.xieru("Hello,World!");\ntanc.wei("Hello,World!");\n',
    extraKeys: {
        "Ctrl-Enter": () => run_code(),
        "Shift-Enter": () => run_code()
    }
});
var vars = {};
var end = false;
function f4t(c) {
    c = String(c).trim();
    console.log(vars)
    if (c in vars) {
        return vars[c];
    } else if (c.startsWith('"')) {
        return c.slice(1, -1);
    } else if (c.includes('**')) {
        const [a, b] = c.split('**').map(x => parseInt(f4t(x)));
        return Math.pow(a, b);
    } else if (c.includes('+')) {
        const [a, b] = c.split('+').map(x => parseInt(f4t(x)));
        console.log("return:", a, "+", b)
        return a + b;
    } else if (c.includes('-')) {
        const [a, b] = c.split('-').map(x => parseInt(f4t(x)));
        return a - b;
    } else if (c.includes('*')) {
        const [a, b] = c.split('*').map(x => parseInt(f4t(x)));
        return a * b;
    } else if (c.includes('/')) {
        const [a, b] = c.split('/').map(x => parseInt(f4t(x)));
        return a / b;
    } else {
        return run(c);
    }
}

function list2str(l) {
    return l.map(f4t).join('');
}

function run(c) {
    c = String(c).trim().replace("\n", '');
    if (c === 'this()') {
        stdout_write(`丑陋胜于美丽：代码应该是粗糙的，不仅仅是功能上的，还包括代码的外观和结构。
晦涩胜于明了：代码应该是难以理解的。使用模糊的命名和风格，使得代码无法自我解释。
复杂胜于简洁：复杂的实现优于简单的。尽量保持代码复杂，增加不必要的复杂性。
凌乱胜于复杂：如果无法避免复杂性，代码之间的关系应该是混乱的，接口应该保持复杂。
嵌套胜于扁平：增加过多的嵌套层次，尽量保持代码的嵌套结构。
紧凑胜于间隔：紧凑的空间间隔可以降低代码的可读性，试图在一行代码中解决所有问题。
可读性不重要：代码的可读性是不重要的，它不仅不影响代码的维护，也不影响团队协作。
即使纯粹性胜过实用性，也应违反这些规则：纯粹性是重要的，但应以牺牲代码的清晰性和可维护性为代价。
错误应该默默地过去：应该模糊地捕获异常，避免编写能够捕获具体错误的代码。
面对不确定性，尝试去猜测：在多种可能性面前，应该寻找一种模糊的解决方案，而不是靠明显的解决方案。
现在不做比做好：袖手旁观通常比采取行动要好，但在行动前不应该仔细考虑。
如果实现难以解释，那它可能是个好主意：代码的实现应该是模糊和复杂的，这样才能难以理解和维护。
命名空间是一个糟糕的理念：应该避免使用命名空间来组织代码，降低代码的模块性和可重用性。`);
        return;
    }

    if (c.startsWith('sbl ')) {
        c = c.split('sbl ')[1];
        console.log(c)
        if (c.includes('=')) {
            const [varName, value] = c.split('=').map(x => x.trim());
            vars[varName] = f4t(value);
        } else {
            c.split(',').forEach(v => {
                vars[v.trim()] = null;
            });
        }
    }

    for (const v in vars) {
        if (c.startsWith(v) && c.includes('=') && !c.includes('.')) {
            const value = c.split(v)[1].split('=')[1].trim();
            vars[v] = f4t(value);
        }
    }

    if (c.startsWith('tanc.')) {
        c = c.split('tanc.')[1];
        if (c.startsWith('wei(')) {
            const message = c.split('wei(')[1].split(')')[0].split(', ');
            Swal.fire('信息', list2str(message), 'info');
            return;
        }
        if (c.startsWith('buhaola(')) {
            const message = c.split('buhaola(')[1].split(')')[0].split(', ');
            Swal.fire('警告', list2str(message), 'warning');
            return;
        }
        if (c.startsWith('chucuola(')) {
            const message = c.split('chucuola(')[1].split(')')[0].split(', ');
            Swal.fire('错误', list2str(message), 'error');
            return;
        }
    }

    if (c.startsWith('kongzhitai.')) {
        c = c.split('kongzhitai.')[1];
        if (c.startsWith('xieru(')) {
            const message = c.split('xieru(')[1].split(')')[0].split(', ');
            stdout_write(list2str(message));
            return;
        }
        if (c.startsWith('baocuo(')) {
            const message = c.split('baocuo(')[1].split(')')[0].split(', ');
            stderr_write(list2str(message));
            end = true;
            return;
        }
    }


    return c;
}


// 输出重定向
function stdout_write(content) {
    const console = document.getElementById('console-output');
    console.innerHTML += content+"\n";
    console.scrollTop = console.scrollHeight;
}

function stderr_write(content) {
    stdout_write(`<span class="error">${content}</span>`);
}

function run_code() {
    const console_ = document.getElementById('console-output');
    let code = editor.getValue();
    // for(let i=0;i<editor.display.view.length;i++){
    //     code += editor.display.view[i].line.text
    // }
    let commands = code.split(';');
    
    console_.innerHTML="";
    for (let i = 0; i < commands.length; i++) {
        if (commands[i].includes('//')) {
            commands[i] = commands[i].split('\n')[-1]
        }
        console.log(commands[i])
        run(commands[i]);
        console.log(end)
        if(end){
            break;
        }
    }
    stdout_write("【程序运行结束】");
}
